﻿using System;
using System.Collections.Generic;
using System.Text;
using BlueFinity.mvNET.CoreObjects;
using IBMU2.UODOTNET;
using mvLibrary.Helpers.Clases.Segurizacion;
using mvLibrary.Helpers.Exceptions;
using mvLibrary.Helpers.Utils;
using mvLibrary.Helpers.Enums;
using mvLibrary.Helpers.BaseClass;
using mvLibrary.Helpers.Querys;
using mvLibrary.Helpers.Utils;

namespace mvLibrary.Helpers
{
    public class ProgramCaller
    {
        private static ProgramCaller instance;
        public SubroutineManager subRoutineManager { get; set; }

        private const string TIPO_PANTALLA_INDEX = "20";
        private const int USER_INDEX = 1;
        private const int CONSULTA_INDEX = 5;
        private const string TIPO_PANTALLA_MENU = "3";
        private const string QUERY_PERMISOS_MENU = "SELECT ACC.PANT.ESP WITH 1 EQ \"{0}\" AND WITH {1} EQ \"{2}\" BY 0";
        private const string QUERY_PERMISOS_USUARIO = "SELECT ACC.LPANT.NET WITH 0 EQ \"{0}\" ";
        private const string QUERY_USUARIOS_CONECTADOS = "LISTU";
        private const string QUERY_PERMISOS_POR_PANTALLA = "SELECT ACC.PANT.ESP WITH 0 EQ \"{0}\" AND WITH 1 EQ \"{1}\" AND WITH 20 EQ \"{2}\" ";

        private ProgramCaller()
        {
            this.subRoutineManager = SubroutineManager.Instance;
        }

        public static ProgramCaller Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ProgramCaller();
                }
                return instance;
            }
        }

        public string ReadNet(UniSession uniSession, string strItem, string itemId, string strMv, string defaultFormule)
        {
            UniSubroutine sub = subRoutineManager.CreateSubRoutine(uniSession, "READ.NET", strItem, itemId,
                                               strMv, defaultFormule, string.Empty);


            return sub.GetLastArgumentAsString();

        }

        public UniDynArray ReadRecord(UniSession uniSession, string itemId, string fileName)
        {
            try
            {

                UniFile file = uniSession.CreateUniFile(fileName);
                return file.Read(itemId);
            }
            catch (UniFileException)
            {
                return new UniDynArray(uniSession);
            }
        }

        public UniSubroutine SaveNet(UniSession uniSession, string strItem, string itemId, string counterFormule, string strItemStatus, string strItemIdType, string nextId, string fileName, string user)
        {
            UniSubroutine sub = subRoutineManager.CreateSubRoutine(uniSession, "SAVE.NET", strItem, itemId, counterFormule,
                                             strItemStatus, strItemIdType, nextId, fileName, user, string.Empty);

            return sub;
        }

        public void SaveItem(UniSession uniSession, string item, string itemId, string fileName, string user)
        {
            subRoutineManager.CreateSubRoutine(uniSession,"SAVE.ITEM", item, itemId, fileName, user);
        }

        public void ValidatePassword(UniSession uniSession, string userId, string password, ref string errorMessage)
        {
            //pickAccount.CallProg("USER.PASSWORD", ref userId, ref password, ref errorMessage);
        }

        public BasicMvItem GetItemById(UniSession uniSession, string itemId, string fileName)
        {
            //string item = string.Empty;
            //pickAccount.CallProg("READ.ITEM.BY.ID", ref item, ref itemId, ref fileName);
            //var itemFromPick = new BasicMvItem(item);

            //return itemFromPick;

            return null;
        }
        public UniDynArray ExecuteSelectNetProgram(UniSession uniSession, string fileName, string attributeNumber,
                                              string sortClause, string selectionClause)
        {
            UniSubroutine sub = subRoutineManager.CreateSubRoutine(uniSession, "SELECT.NET", fileName, attributeNumber,
                                               sortClause, selectionClause, string.Empty);
            return sub.GetLastArgument();
        }

        public string ExecuteReportNetProgram(UniSession uniSession, string user, string tclCommand, string parameters)
        {
            string report = string.Empty;

            UniSubroutine sub = subRoutineManager.CreateSubRoutine(uniSession, "REPORT.NET", user, tclCommand,
                                               parameters, report);

            return sub.GetLastArgumentAsString();

        }

        public UniSubroutine CallProgram(UniSession uniAccount, string programName, string strItem, string strOldItem, string _itemId, string strItemStatus, string FileName, string formName, string strAttribute, string strMv, string _defaultValue, string _inputValue, string strData, string _user, string _userLevel, string strPrinterSwitch, string _defaultPickPrinter, string _copyFrom, string _subErr, string _errorMessage)
        {
            UniSubroutine sub = subRoutineManager.CreateSubRoutine(uniAccount, programName, strItem, strOldItem, _itemId, strItemStatus, FileName, formName, strAttribute, strMv, _defaultValue, _inputValue, strData, _user, _userLevel, strPrinterSwitch, _defaultPickPrinter, _copyFrom, _subErr, _errorMessage);

            return sub;
        }

        public UniSelectList GetPermisosPorUsuarios(UniSession uniAccount, string userId)
        {
            try
            {
                var tclCommand = string.Format(QUERY_PERMISOS_USUARIO, userId);
                UniCommand queryCommand = uniAccount.CreateUniCommand();

                queryCommand.Command = tclCommand;
                queryCommand.Execute();
                return uniAccount.CreateUniSelectList(0);
            }
            catch (mvException ex)
            {
                throw new PermissionsException(ex);
            }


        }
        /*
         * Este metodo se encarga de buscar en el archivo ACC.PANT.ESP, 
         * los permisos para los distintos menues de la aplicacion,
         * para el usuario que se esta logueando.
         * Luego devuelve un objeto con toda la informacion.
         */
        public IList<string> GetMenuPermissionsFromPick(UniSession uniAccount, string userId)
        {
            var result = new List<string>();

            try
            {
                UniCommand queryCommand = uniAccount.CreateUniCommand();

                var tclCommand = string.Format(QUERY_PERMISOS_MENU, userId, TIPO_PANTALLA_INDEX, TIPO_PANTALLA_MENU);

                queryCommand.Command = tclCommand;
                queryCommand.Execute();

                var list = uniAccount.CreateUniSelectList(0);

                while (!list.LastRecordRead)
                {
                    string menuId = list.Next();
                    if (!string.IsNullOrEmpty(menuId))
                    {
                        result.Add(menuId);
                    }
                }
            }
            catch (Exception ex)
            {
                //throw new PermissionsException(ex);
            }
            return result;

        }


        public mvItem GetPermissionsPorPantalla(string pantalla, int tipoPantalla, UniSession uniAccount, string userId)
        {
            try
            {
                UniCommand queryCommand = uniAccount.CreateUniCommand();

                var tclCommand = string.Format(QUERY_PERMISOS_POR_PANTALLA, pantalla, userId, tipoPantalla);

                queryCommand.Command = tclCommand;
                queryCommand.Execute();

                var list = uniAccount.CreateUniSelectList(0);

                string menuId = list.Next();

                if (string.IsNullOrEmpty(menuId))
                {
                    throw new PermissionsException(string.Empty);
                }
            }
            catch (Exception ex)
            {
                throw new PermissionsException(ex);
            }

            return null;
        }



        public string CheckUserLicense(UniSession uniSession,string formName, string userID)
        {
            string report = string.Empty;

            UniSubroutine sub = subRoutineManager.CreateSubRoutine(uniSession, "CHECK.USER.LICENCE", formName, userID,string.Empty);

            return sub.GetLastArgumentAsString().ToString();
        }
    }
}
